package cn.wqb.bpp.common.utils;

import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.util.StringUtils;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;

public class ImageUtils {

    /**
     * 保存文件到Recources目录下的静态目录（仅推荐保存少量系统文件使用，大量用户文件建议保存到指定文件服务器或独立的系统目录）
     *
     * @param multipartFile
     * @param savePath      例：upload/xxx.jpg
     * @return 成功返回true，失败返回false
     */
    public static boolean saveImgToStaticPath(MultipartFile multipartFile, String savePath, int maxHeight) {
        if (StringUtils.isEmpty(savePath)) {
            LogUtils.instance(ImageUtils.class).error("savePath为空");
            return false;
        }
        String fullPath = "";
        try {
            fullPath = ResourceUtils.getURL("classpath:").getPath() + savePath;
            fullPath = fullPath.replace("//", "/");
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error("classpath目录获取失败" + e);
            return false;
        }
        File file = new File(fullPath);
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        try {
            String formatName = savePath.substring(savePath.lastIndexOf(".") + 1);
            BufferedImage image = ImageIO.read(multipartFile.getInputStream());
            int height = image.getHeight(null);
            if (height > maxHeight) {
                height = maxHeight;
                int width = height * image.getWidth(null) / image.getHeight(null);
                BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.SCALE_SMOOTH);
                Graphics graphics = bufferedImage.getGraphics();
                graphics.drawImage(image, 0, 0, width, height, null);
                graphics.dispose();
                ImageIO.write(bufferedImage, formatName, file);
            } else {
                ImageIO.write(image, formatName, file);
            }
            return true;
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error("保存文件失败：" + e);
        }
        return false;
    }

    /**
     * 删除文件
     *
     * @param filePath
     * @return
     */
    public static boolean deleteImgFromStaticPath(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            return false;
        }
        String fullPath = "";
        try {
            fullPath = ResourceUtils.getURL("classpath:").getPath() + filePath;
            fullPath = fullPath.replace("//", "/");
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error(e + ">>>>>>>>>>Cause:" + e.getCause());
            return false;
        }
        File file = new File(fullPath);
        if (file.exists()) {
            return file.delete();
        } else {
            return true;
        }
    }

    /**
     * 从MultipartFile中获取Base64
     */
    public static String getBase64FromMultipartFile(MultipartFile multipartFile, int maxHeight) {
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            BufferedImage image = ImageIO.read(multipartFile.getInputStream());
            int height = image.getHeight(null);
            if (height > maxHeight) {
                height = maxHeight;
                int width = height * image.getWidth(null) / image.getHeight(null);
                BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.SCALE_SMOOTH);
                Graphics graphics = bufferedImage.getGraphics();
                graphics.drawImage(image, 0, 0, width, height, null);
                graphics.dispose();
                ImageIO.write(bufferedImage, "jpg", outputStream);
            } else {
                ImageIO.write(image, "jpg", outputStream);
            }
            byte[] bytes = outputStream.toByteArray();
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encodeBuffer(bytes);
            base64 = base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
            return "data:img/jpg;base64," + base64;
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error("从MultipartFile中获取Base64失败：" + e);
        }
        return null;
    }

    /**
     * 获取网络图片的Base64
     *
     * @param url
     * @return
     */
    public static String getImageBase64FromHttpUrl(String url) {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            InputStream inStream = conn.getInputStream();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }
            inStream.close();
            byte[] data = outStream.toByteArray();
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encode(data);
            return "data:img/png;base64," + base64;
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error(e + ">>>>>>>>>>Cause:" + e.getCause());
        }
        return null;
    }

    /**
     * BufferedImage转成Base64
     *
     * @param bufferedImage
     * @return
     */
    public static String bufferedImageToBase64(BufferedImage bufferedImage) {
        try {
            byte[] bytes = bufferedImageToBytes(bufferedImage);
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encodeBuffer(bytes).trim();
            base64 = base64.replaceAll("\n", "").replaceAll("\r", "");
            return "data:image/png;base64," + base64;
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error(e.getCause());
        }
        return null;
    }

    /**
     * BufferedImage转成byte[]
     *
     * @param bufferedImage
     * @return
     */
    public static byte[] bufferedImageToBytes(BufferedImage bufferedImage) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "png", baos);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
            LogUtils.instance(ImageUtils.class).error(e.getCause());
        }
        return null;
    }

    public static String bytesToBase64(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }

    public static byte[] base64ToBytes(String base64) {
        return Base64.getDecoder().decode(base64);
    }
}
